#ifndef _SIGNAL_H
#define _SIGNAL_H

#include <sys/types.h>  // 类型头文件 定义了基本的系统数据类型

typedef int sig_atomic_t;   // 定义信号原子操作类型
typedef unsigned int sigset_t;		/* 32 bits */   // 定义信号集类型

#define _NSIG             32    // 定义信号种类 -- 32种
#define NSIG		_NSIG       // NSIG = _NSIG
// 以下这些是 Linux 0.11 内核中定义的信号
#define SIGHUP		 1  // 挂断控制终端或进程
#define SIGINT		 2  // 来自键盘的中断
#define SIGQUIT		 3  // 来自键盘的退出
#define SIGILL		 4  // 非法指令
#define SIGTRAP		 5  // 跟踪断点
#define SIGABRT		 6  // 异常结束
#define SIGIOT		 6  // 同上
#define SIGUNUSED	 7  // 没有使用
#define SIGFPE		 8  // 协处理器出错
#define SIGKILL		 9  // 强迫进程终止
#define SIGUSR1		10  // 用户信号1 进程可使用
#define SIGSEGV		11  // 无效内存引用
#define SIGUSR2		12  // 用户信号2 进程可使用
#define SIGPIPE		13  // 管道写出错 无读者
#define SIGALRM		14  // 实时定时器报警
#define SIGTERM		15  // 进程终止
#define SIGSTKFLT	16  // 栈出错（协处理器）
#define SIGCHLD		17  // 子进程停止或被终止
#define SIGCONT		18  // 恢复进程继续执行
#define SIGSTOP		19  // 停止进程的执行
#define SIGTSTP		20  // tty 发布停止进程
#define SIGTTIN		21  // 后台进程请求输入
#define SIGTTOU		22  // 后台进程请求输出
// 我还没有实现 sigactions 的编制 但在头文件中仍希望遵守POSX标准
/* Ok, I haven't implemented sigactions, but trying to keep headers POSIX */
#define SA_NOCLDSTOP	1       // 当子进程处于停止状态 就不对 SIGCHLD 处理
#define SA_NOMASK	0x40000000  // 不阻止在指定的信号处理程序（信号句柄）中再收到该信号
#define SA_ONESHOT	0x80000000  // 信号句柄一旦被调用过就恢复到默认处理句柄
// 以下参数用于 sigprocmask（）-改变阻塞信号集（屏蔽码） 这些参数可以改变该函数的行为
#define SIG_BLOCK          0	/* for blocking signals */  // 在阻塞信号集中加上给定的信号集
#define SIG_UNBLOCK        1	/* for unblocking signals */    // 从阻塞信号集中删除指定的信号集
#define SIG_SETMASK        2	/* for setting the signal mask */   // 色值阻塞信号集（信号屏蔽码）

#define SIG_DFL		((void (*)(int))0)	/* default signal handling */   // 默认的信号处理程序（信号句柄）
#define SIG_IGN		((void (*)(int))1)	/* ignore signal */ // 忽略信号的处理程序
// 下面是 sigaction 的数据结构
struct sigaction {  // sa_handle 是对应某信号指定要采取的行动 可以是上面的 SIG_DFL 或者是SIG_IGN来忽略该信号来忽略该信号 也可以是指向处理该信号函数的一个指针 sa_mask给出了对信号的屏蔽码 在信号程序执行时将阻塞对这些信号的处理 sa_flags指定改变信号处理过程的信号集 它是由37-39行的位标志定义的 sa_restorer恢复函数指针 由函数库Libc提供 用于清理用户态堆栈 另外 引起出发信号处理的信号也将被阻塞 除非使用了 SA_NOMASK标志
	void (*sa_handler)(int);
	sigset_t sa_mask;
	int sa_flags;
	void (*sa_restorer)(void);
};
// 为信号sig安装一个新的信号处理程序（信号句柄）与 sigaction（）类似
void (*signal(int _sig, void (*_func)(int)))(int);
int raise(int sig); // 向当前进程发送一个信号 其作用等价于kill（getpid（），sig）
int kill(pid_t pid, int sig);   // 可用于向任何进程组或进程发送任何信号
int sigaddset(sigset_t *mask, int signo);   // 向信号集中添加信号
int sigdelset(sigset_t *mask, int signo);   // 从信号集中取出指定的信号
int sigemptyset(sigset_t *mask);            // 从信号集中清楚指定信号集
int sigfillset(sigset_t *mask);             // 向信号集中置入所有信号
int sigismember(sigset_t *mask, int signo); /* 1 - is, 0 - not, -1 error */ // 判断一个信号是不是信号集中的 1-是 0-不是 -1-出错
int sigpending(sigset_t *set);              // 对set中的信号进行检测 看是否有挂起的信号
int sigprocmask(int how, sigset_t *set, sigset_t *oldset);  // 改变目前的被阻塞信号集
int sigsuspend(sigset_t *sigmask);  // 用sigmask临时替换进程的信号屏蔽码 然后暂停该进程知道收到一个信号
int sigaction(int sig, struct sigaction *act, struct sigaction *oldact);    // 用于改变进程在收到指定信号时所采取的行动

#endif /* _SIGNAL_H */
